/****************************************************************************
**
****************************************************************************/

#include <QReadWriteLock>

#include "util.h"
#include "hciMain.h"
#include "oiovMain.h"
#include "oiovCallback.h"
#include "baseConfigure.h"
#include "baseUpdate.h"

#include "../../iov/operation/operation_protocol.h"
#include "../../iov/sdk/core/aiot_state_api.h"

#include <QDebug>
#define OIOVMAIN_DEBUG

/*------------------------------------------------------------------------------------------------------------------------------------------------*/

bool OiovResMain::net_state_ = false;

OiovResMain::OiovResMain(QObject *parent) : QThread(parent),
    m_quit(false),
    m_cycle(200)
{

}

OiovResMain::~OiovResMain()
{
    m_quit = true;
    wait();
}

qint32 OiovResMain::loop()
{
    int resA = 0, resB = 0;

    static qint32 loopStepA = 0, loopStepB = 0;
    static qint32 authCountA = 0, authCountB = 0;

    switch (loopStepA) {
    case OPERATION_LINKKIT_AUTH:
        if (0 == (authCountA % (30 * 1000 / m_cycle))) {
            ops_network_deinit(OPSGUNNOA);
            resA = ops_auth(OPSGUNNOA, &OiovCallback::ops_event_sign_in[0], sizeof(ops_event_sign_in_t));
            if (STATE_SUCCESS <= resA) {
                qDebug() << "[OIOV]-> No.a authorize success";
                loopStepA++;
                authCountA = 0;
//                msleep(1000);
//                ops_send_event(OPSGUNNOA, OPS_CMD_EVENT_FEE_STRATEGY, &OiovCallback::ops_event_fee_strategy); // A 抢授权成功后向平台获取计费模型
                msleep(1000);
            } else {
//                qDebug() << "[OIOV]-> No.a authorize failed, reason:" << resA;
                qDebug() << "[OIOV]-> No.a authorize failed, reason:" << QString::number(resA, 16).toUpper();
                authCountA++;
                return OPERATION_LINKKIT_AUTH_FAULT;
            }
        } else {
            authCountA++;
            return OPERATION_LINKKIT_AUTH_WAIT;
        }
        break;
    case OPERATION_LINKKIT_POLL:
        resA = ops_yield(OPSGUNNOA);
        if (STATE_SUCCESS > resA) {
            if (STATE_ITCP_RECV_NOT_FINISHED != resA && STATE_ITCP_HEADER_INVALID != resA) {
                qDebug() << "[OIOV]-> No.a yield failed, reason:" << resA;
                loopStepA = 0;
                authCountA = 0;
                loopStepB = 0;
                authCountB = 0;
                return OPERATION_LINKKIT_POLL_FAULT; //重新授权
            }
        }
        break;
    default:
        break;
    }

    return 0;
}

void OiovResMain::run()
{
//#ifndef __arm__
//    return;
//#endif

    /* ykc - test - aliyun
    char   *ops_eth  = (char *)"eth1";
    char   *ops_host = (char *)"121.199.192.223";
    quint16 ops_port = 8768; */

    /* ykc - test
    char   *ops_eth  = (char *)"eth1";
    char   *ops_host = (char *)"121.199.192.223";
    quint16 ops_port = 8767; */

    /* ykc - release
    char   *ops_eth  = (char *)"eth1";
    char   *ops_host = (char *)"121.43.69.62";
    quint16 ops_port = 8767; */

    BaseConfigure::set_net_ip("139.198.163.108");
    BaseConfigure::set_net_port(8008);


    QByteArray array = BaseConfigure::net_ip().toLatin1();

    char   *ops_eth  = NULL;
    char   *ops_host = array.data();
    quint16 ops_port = BaseConfigure::net_port();

    if (0 > ops_linkkit_new(ops_eth, ops_host, ops_port)) {
        return;
    }

    OiovReqMain::SetCheck_Fee(0);
    OiovReqMain::SetReq_Fee();
    OiovReqMain::SetDeviceStatusEvent(0);
    OiovReqMain::SetDeviceStatusEvent(1);


    while (1) {
        if (0 > loop()) {
            net_state_ = false;
        } else {
            net_state_ = true;
        }

        if (100 > m_cycle) {
            m_cycle = 100;
        }
        msleep(m_cycle);
    }
}

/*------------------------------------------------------------------------------------------------------------------------------------------------*/

static QReadWriteLock AppStartChargeServiceLock;
static QReadWriteLock AppStopChargeServiceLock;
static QReadWriteLock CardAuthStartChargeServiceLock;

static QReadWriteLock CardAuthChargeEventLock;
static QReadWriteLock StopChargeEventLock;
static QReadWriteLock DeviceStatusEventLock;
static QReadWriteLock HearbeatEventLock;

static QReadWriteLock ChargingPropertyLock;

//Update - flag
bool OiovReqMain::start_update_ = false;

//cmd flag
QList<bool> OiovReqMain::app_start_charge_service_ = {false, false};
QList<bool> OiovReqMain::app_stop_charge_service_ = {false, false};
QList<bool> OiovReqMain::card_auth_start_charge_service_ = {false, false};

//event flag
QList<bool> OiovReqMain::card_auth_charge_event_ = {false, false};
QList<bool> OiovReqMain::stop_charge_event_ = {false, false};
bool        OiovReqMain::rebill_charge_event_ = false;
QList<bool> OiovReqMain::device_status_event_ = {false, false};
QList<bool> OiovReqMain::hearbeat_event_ = {false, false};

//property flag
QList<bool> OiovReqMain::charging_property_  = {false, false};

static void ascii_to_bcd(char *ascii, char *bcd, uint8_t len)
{
    uint8_t index;
    char c;

    for (index = 0; index < len; index++) {
        c  = (*ascii++) << 4;
        c |= (*ascii++) & 0x0F;
        *bcd++ = c;
    }
}

static uint16_t crc16_modbus(uint16_t crc, uint8_t *data, uint32_t len)
{
    static uint16_t crc_talbe[] = {
        0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
        0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,
    };

    uint32_t i = 0;
    uint8_t ch;

    for (i = 0; i < len; i++) {
        ch = *data++;
        crc = crc_talbe[(ch ^ crc) & 15] ^ (crc >> 4);
        crc = crc_talbe[((ch >> 4) ^ crc) & 15] ^ (crc >> 4);
    }

    return crc;
}

OiovReqMain::OiovReqMain(QObject *parent) : QThread(parent),
    m_quit(false)
{
    Int_pill_number();
}

OiovReqMain::~OiovReqMain()
{
    m_quit = true;
    wait();
}

void OiovReqMain::Int_pill_number(void)
{
    BaseConfigure::set_pile_model("202412021215");
    BaseConfigure::set_pile_vendor("202412021215");

    char version[8] = {0};
    version[0] = TCU_SOFTWARE_VERSION + '0';
    version[1] = '.';
    version[2] = TCU_SOFTWARE_SUBVERSION + '0';
    version[3] = '.';
    sprintf((char *)&version[3 + 1], "%.2d", TCU_SOFTWARE_REVISION);
    char pile_number_bcd[7] = {0};

    ascii_to_bcd(BaseConfigure::pile_model().toLatin1().data(), pile_number_bcd, sizeof(pile_number_bcd));

    for (int index = 0; index < OPS_MAX_PORT_NUM; index++) {
        /* 初始化登陆签到请求 */
        qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << BaseConfigure::gun_number(index);
        OiovCallback::ops_event_sign_in[index].head.magin = OPS_MAGIC;
        OiovCallback::ops_event_sign_in[index].head.length = 2 + 2 + (sizeof(ops_event_sign_in_t) - sizeof(ops_head_t) - 2);
        OiovCallback::ops_event_sign_in[index].head.seq = 0x0000;
        OiovCallback::ops_event_sign_in[index].head.encrypt = OPS_ENCRYPT_FLAG;
        OiovCallback::ops_event_sign_in[index].head.opcode = OPS_CMD_EVENT_SIGN_IN;
        memset(OiovCallback::ops_event_sign_in[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_sign_in[index].pill_number));
        memcpy(OiovCallback::ops_event_sign_in[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_event_sign_in[index].pile_type = OPS_CHARGINGPILE_TYPE;
        OiovCallback::ops_event_sign_in[index].gun_count = OPS_MAX_PORT_NUM;
        OiovCallback::ops_event_sign_in[index].protocol_version = OPS_VERSION;
        memset(OiovCallback::ops_event_sign_in[index].soft_version, 0x00, sizeof(OiovCallback::ops_event_sign_in[index].soft_version));
        memcpy(OiovCallback::ops_event_sign_in[index].soft_version, version, strlen((const char *)version));
        OiovCallback::ops_event_sign_in[index].net_type = 0x00;
        memset(OiovCallback::ops_event_sign_in[index].sim_no, 0x00, sizeof(OiovCallback::ops_event_sign_in[index].sim_no));
        OiovCallback::ops_event_sign_in[index].mnc = 0x04;
        OiovCallback::ops_event_sign_in[index].crc =
            crc16_modbus(0xFFFF, (uint8_t *)(&(OiovCallback::ops_event_sign_in[index].head.seq)), sizeof(OiovCallback::ops_event_sign_in[index]) - 1 - 1 - 2);

        /* 初始化心跳请求 */
        memset(OiovCallback::ops_event_heartbeat[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_heartbeat[index].pill_number));
        memcpy(OiovCallback::ops_event_heartbeat[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_event_heartbeat[index].gun_number = index + OPSGUNNOA;
        OiovCallback::ops_event_heartbeat[index].gun_state = OiovCallback::OPS_CHARGINGGUN_STATE_NORMAL;

        /* 初始化计费模型校验请求 */
        memset(OiovCallback::ops_event_check_fee.pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_check_fee.pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_event_check_fee.fee_mode_no =  0;

        /* 初始化BMS各阶段上报*/
        OiovCallback::ops_event_charge_handshake[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_handshake[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_handshake[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_set_value[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_set_value[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_set_value[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_charge_complete[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_complete[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_complete[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_error[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_error[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_error[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_charge_abort[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_abort[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_abort[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_charge_stop[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_stop[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_stop[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_charge_output[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_output[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_output[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));

        OiovCallback::ops_event_charge_process_status[index].gun_number = index + 1;
        memset(OiovCallback::ops_event_charge_process_status[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_check_fee.pill_number));
        memcpy(OiovCallback::ops_event_charge_process_status[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));


        /* 初始化账单（交易记录）请求 */
        memset(OiovCallback::ops_event_bill[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_bill[index].pill_number));
        memcpy(OiovCallback::ops_event_bill[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_event_bill[index].gun_number = index + OPSGUNNOA;

        /* 初始化实时数据请求 */
        memset(OiovCallback::ops_property_charge_data[index].serial_number, 0x00, sizeof(OiovCallback::ops_property_charge_data[index].serial_number));
        memset(OiovCallback::ops_property_charge_data[index].pill_number, 0x00, sizeof(OiovCallback::ops_property_charge_data[index].pill_number));
        memcpy(OiovCallback::ops_property_charge_data[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_property_charge_data[index].gun_number = index + OPSGUNNOA;
        OiovCallback::ops_property_charge_data[index].status = OiovCallback::OPS_CHARGINGPILE_STATE_IDLE;
        OiovCallback::ops_property_charge_data[index].regun = 0x02; /* 未知 */
        OiovCallback::ops_property_charge_data[index].connect_gun = OiovCallback::OPS_GUN_CONNECT_STATE_NOT;
        memset(OiovCallback::ops_property_charge_data[index].line_number, 0x00, sizeof(OiovCallback::ops_property_charge_data[index].line_number));
        OiovCallback::ops_property_charge_data[index].soc = 0x00;
        OiovCallback::ops_property_charge_data[index].battery_max_temp = 0x00;
        OiovCallback::ops_property_charge_data[index].remaining_charging_time = 0x00;

        /* 初始化在线鉴权请求 */
        memset(OiovCallback::ops_event_card_authorize[index].pill_number, 0x00, sizeof(OiovCallback::ops_event_card_authorize[index].pill_number));
        memcpy(OiovCallback::ops_event_card_authorize[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
        OiovCallback::ops_event_card_authorize[index].gun_number = index + OPSGUNNOA;

        /* 初始化远程升级应答 */
        memset(OiovCallback::ops_active_service_feedback_start_update[index].pill_number, 0x00, sizeof(OiovCallback::ops_active_service_feedback_start_update[index].pill_number));
        memcpy(OiovCallback::ops_active_service_feedback_start_update[index].pill_number, pile_number_bcd, sizeof(pile_number_bcd));
    }

    /* 初始化计费策略请求 */
    memset(OiovCallback::ops_event_fee_strategy.pill_number, 0x00, sizeof(OiovCallback::ops_event_fee_strategy.pill_number));
    memcpy(OiovCallback::ops_event_fee_strategy.pill_number, pile_number_bcd, sizeof(pile_number_bcd));

}

void OiovReqMain::Updata_serial_number(uint8_t index)
{
    char pile_number_bcd[16] = {0};

    // 从 ops_active_service_start_charging_app 中获取 serial_number
    memcpy(pile_number_bcd, OiovCallback::ops_active_service_start_charging_app[index].serial_number, sizeof(pile_number_bcd));

    /* BMS各阶段上报*/
    memset(OiovCallback::ops_event_charge_handshake[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_handshake[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_handshake[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_set_value[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_set_value[index].serial_number));
    memcpy(OiovCallback::ops_event_set_value[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_charge_complete[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_complete[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_complete[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_error[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_error[index].serial_number));
    memcpy(OiovCallback::ops_event_error[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_charge_abort[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_abort[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_abort[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_charge_stop[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_stop[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_stop[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_charge_output[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_output[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_output[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));

    memset(OiovCallback::ops_event_charge_process_status[index].serial_number, 0x00, sizeof(OiovCallback::ops_event_charge_process_status[index].serial_number));
    memcpy(OiovCallback::ops_event_charge_process_status[index].serial_number, pile_number_bcd, sizeof(pile_number_bcd));


    quint8 gun_test_no = 1;
    gun_test_no = index;
    OiovReqMain::SetCharge_Handshake(gun_test_no);
    OiovReqMain::SetBMS_Charge_Complete(gun_test_no);
    OiovReqMain::SetBMS_Error(gun_test_no);
    OiovReqMain::SetBMS_Set_Value(gun_test_no);
    OiovReqMain::SetBMS_Charge_Abort(gun_test_no);
    OiovReqMain::SetBMS_Charge_Stop(gun_test_no);
    OiovReqMain::SetBMS_Charge_Output(gun_test_no);
    OiovReqMain::SetBMS_Process_Status(gun_test_no);
}

static QReadWriteLock firmware_status_event;
QList<bool> OiovReqMain::firmware_status_event_ = {false, false};

bool OiovReqMain::FirmwareStatusEvent(quint8 gunno)
{
    bool res = false;

    firmware_status_event.lockForRead();
    res = firmware_status_event_.at(gunno);
    firmware_status_event.unlock();

    return res;
}
void OiovReqMain::SetFirmwareStatusEvent(quint8 gunno)
{
    firmware_status_event.lockForWrite();
    firmware_status_event_.replace(gunno, true);
    firmware_status_event.unlock();
}
void OiovReqMain::ClearFirmwareStatusEvent(quint8 gunno)
{
    firmware_status_event.lockForWrite();
    firmware_status_event_.replace(gunno, false);
    firmware_status_event.unlock();
}

static QReadWriteLock request_fee_lock;
bool OiovReqMain::request_fee_event_ = false;

bool OiovReqMain::Req_Fee(void)
{
    return request_fee_event_;
}

void OiovReqMain::SetReq_Fee( void)
{
    request_fee_lock.lockForWrite();
    request_fee_event_ = true;
    request_fee_lock.unlock();
}

void OiovReqMain::ClearReq_Fee(void)
{
    request_fee_lock.lockForWrite();
    request_fee_event_ = false;
    request_fee_lock.unlock();
}


static QReadWriteLock check_fee_lock;
QList<bool> OiovReqMain::check_fee_event_ = {false, false};

bool OiovReqMain::Check_Fee(quint8 gunno)
{
    bool res = false;

    check_fee_lock.lockForRead();
    res = check_fee_event_.at(gunno);
    check_fee_lock.unlock();

    return res;
}

void OiovReqMain::SetCheck_Fee(quint8 gunno)
{
    check_fee_lock.lockForWrite();
    check_fee_event_.replace(gunno, true);
    check_fee_lock.unlock();
}

void OiovReqMain::ClearCheck_Fee(quint8 gunno)
{
    check_fee_lock.lockForWrite();
    check_fee_event_.replace(gunno, false);
    check_fee_lock.unlock();
}
/*
 *
 * BMS updata
*/
static QReadWriteLock Charge_HandshakeLock;
QList<bool> OiovReqMain::Charge_Handshake_ = {false, false};

bool OiovReqMain::Charge_Handshake(quint8 gunno)
{
    bool res = false;

    Charge_HandshakeLock.lockForRead();
    res = Charge_Handshake_.at(gunno);
    Charge_HandshakeLock.unlock();

    return res;
}

void OiovReqMain::SetCharge_Handshake(quint8 gunno)
{
    Charge_HandshakeLock.lockForWrite();
    Charge_Handshake_.replace(gunno, true);
    Charge_HandshakeLock.unlock();
}

void OiovReqMain::ClearCharge_Handshake(quint8 gunno)
{
    Charge_HandshakeLock.lockForWrite();
    Charge_Handshake_.replace(gunno, false);
    Charge_HandshakeLock.unlock();
}
/*
 *
*/

// 每个状态的 QReadWriteLock 锁
static QReadWriteLock BMS_Charge_Complete_Lock;
static QReadWriteLock BMS_Error_Lock;
static QReadWriteLock BMS_Set_Value_Lock;
static QReadWriteLock BMS_Charge_Abort_Lock;
static QReadWriteLock BMS_Charge_Stop_Lock;
static QReadWriteLock BMS_Charge_Output_Lock;
static QReadWriteLock BMS_Process_Status_Lock;

// 各状态变量
QList<bool> OiovReqMain::BMS_Charge_Complete_ = {false, false};
QList<bool> OiovReqMain::BMS_Error_ = {false, false};
QList<bool> OiovReqMain::BMS_Set_Value_ = {false, false};
QList<bool> OiovReqMain::BMS_Charge_Abort_ = {false, false};
QList<bool> OiovReqMain::BMS_Charge_Stop_ = {false, false};
QList<bool> OiovReqMain::BMS_Charge_Output_ = {false, false};
QList<bool> OiovReqMain::BMS_Process_Status_ = {false, false};


bool OiovReqMain::BMS_Charge_Complete(quint8 gunno)
{
    bool res = false;

    BMS_Charge_Complete_Lock.lockForRead();  // 读锁
    res = BMS_Charge_Complete_.at(gunno);
    BMS_Charge_Complete_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Charge_Complete(quint8 gunno)
{
    BMS_Charge_Complete_Lock.lockForWrite();  // 写锁
    BMS_Charge_Complete_.replace(gunno, true);
    BMS_Charge_Complete_Lock.unlock();
}

void OiovReqMain::ClearBMS_Charge_Complete(quint8 gunno)
{
    BMS_Charge_Complete_Lock.lockForWrite();  // 写锁
    BMS_Charge_Complete_.replace(gunno, false);
    BMS_Charge_Complete_Lock.unlock();
}

bool OiovReqMain::BMS_Set_Value(quint8 gunno)
{
    bool res = false;

    BMS_Set_Value_Lock.lockForRead();  // 读锁
    res = BMS_Set_Value_.at(gunno);
    BMS_Set_Value_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Set_Value(quint8 gunno)
{
    BMS_Set_Value_Lock.lockForWrite();  // 写锁
    BMS_Set_Value_.replace(gunno, true);
    BMS_Set_Value_Lock.unlock();
}

void OiovReqMain::ClearBMS_Set_Value(quint8 gunno)
{
    BMS_Set_Value_Lock.lockForWrite();  // 写锁
    BMS_Set_Value_.replace(gunno, false);
    BMS_Set_Value_Lock.unlock();
}

bool OiovReqMain::BMS_Error(quint8 gunno)
{
    bool res = false;

    BMS_Error_Lock.lockForRead();  // 读锁
    res = BMS_Error_.at(gunno);
    BMS_Error_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Error(quint8 gunno)
{
    BMS_Error_Lock.lockForWrite();  // 写锁
    BMS_Error_.replace(gunno, true);
    BMS_Error_Lock.unlock();
}

void OiovReqMain::ClearBMS_Error(quint8 gunno)
{
    BMS_Error_Lock.lockForWrite();  // 写锁
    BMS_Error_.replace(gunno, false);
    BMS_Error_Lock.unlock();
}


bool OiovReqMain::BMS_Charge_Abort(quint8 gunno)
{
    bool res = false;

    BMS_Charge_Abort_Lock.lockForRead();  // 读锁
    res = BMS_Charge_Abort_.at(gunno);
    BMS_Charge_Abort_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Charge_Abort(quint8 gunno)
{
    BMS_Charge_Abort_Lock.lockForWrite();  // 写锁
    BMS_Charge_Abort_.replace(gunno, true);
    BMS_Charge_Abort_Lock.unlock();
}

void OiovReqMain::ClearBMS_Charge_Abort(quint8 gunno)
{
    BMS_Charge_Abort_Lock.lockForWrite();  // 写锁
    BMS_Charge_Abort_.replace(gunno, false);
    BMS_Charge_Abort_Lock.unlock();
}


bool OiovReqMain::BMS_Charge_Stop(quint8 gunno)
{
    bool res = false;

    BMS_Charge_Stop_Lock.lockForRead();  // 读锁
    res = BMS_Charge_Stop_.at(gunno);
    BMS_Charge_Stop_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Charge_Stop(quint8 gunno)
{
    BMS_Charge_Stop_Lock.lockForWrite();  // 写锁
    BMS_Charge_Stop_.replace(gunno, true);
    BMS_Charge_Stop_Lock.unlock();
}

void OiovReqMain::ClearBMS_Charge_Stop(quint8 gunno)
{
    BMS_Charge_Stop_Lock.lockForWrite();  // 写锁
    BMS_Charge_Stop_.replace(gunno, false);
    BMS_Charge_Stop_Lock.unlock();
}


int OiovReqMain::BMS_Charge_Output(quint8 gunno)
{
    int res = 0;

    BMS_Charge_Output_Lock.lockForRead();  // 读锁
    res = BMS_Charge_Output_.at(gunno);
    BMS_Charge_Output_Lock.unlock();

    return res;
}

void OiovReqMain::SetBMS_Charge_Output(quint8 gunno)
{
    BMS_Charge_Output_Lock.lockForWrite();  // 写锁
    BMS_Charge_Output_.replace(gunno, true);
    BMS_Charge_Output_Lock.unlock();
}

void OiovReqMain::ClearBMS_Charge_Output(quint8 gunno)
{
    BMS_Charge_Output_Lock.lockForWrite();  // 写锁
    BMS_Charge_Output_.replace(gunno, false); // 清除输出
    BMS_Charge_Output_Lock.unlock();
}


int OiovReqMain::BMS_Process_Status(quint8 gunno)
{
    int status = 0;

    BMS_Process_Status_Lock.lockForRead();  // 读锁
    status = BMS_Process_Status_.at(gunno);
    BMS_Process_Status_Lock.unlock();

    return status;
}

void OiovReqMain::SetBMS_Process_Status(quint8 gunno)
{
    BMS_Process_Status_Lock.lockForWrite();  // 写锁
    BMS_Process_Status_.replace(gunno, true);
    BMS_Process_Status_Lock.unlock();
}

void OiovReqMain::ClearBMS_Process_Status(quint8 gunno)
{
    BMS_Process_Status_Lock.lockForWrite();  // 写锁
    BMS_Process_Status_.replace(gunno, false);  // 0 表示清除状态，可能是空闲状态
    BMS_Process_Status_Lock.unlock();
}



/*
 *
 * BMS updata
*/

bool OiovReqMain::AppStartChargeService(quint8 gunno)
{
    bool res = false;

    AppStartChargeServiceLock.lockForRead();
    res = app_start_charge_service_.at(gunno);
    AppStartChargeServiceLock.unlock();

    return res;
}

void OiovReqMain::SetAppStartChargeService(quint8 gunno)
{
    AppStartChargeServiceLock.lockForWrite();
    app_start_charge_service_.replace(gunno, true);
    AppStartChargeServiceLock.unlock();
}

void OiovReqMain::ClearAppStartChargeService(quint8 gunno)
{
    AppStartChargeServiceLock.lockForWrite();
    app_start_charge_service_.replace(gunno, false);
    AppStartChargeServiceLock.unlock();
}

bool OiovReqMain::AppStopChargeService(quint8 gunno)
{
    bool res = false;

    AppStopChargeServiceLock.lockForRead();
    res = app_stop_charge_service_.at(gunno);
    AppStopChargeServiceLock.unlock();

    return res;
}

void OiovReqMain::SetAppStopChargeService(quint8 gunno)
{
    AppStopChargeServiceLock.lockForWrite();
    app_stop_charge_service_.replace(gunno, true);
    AppStopChargeServiceLock.unlock();
}

void OiovReqMain::ClearAppStopChargeService(quint8 gunno)
{
    AppStopChargeServiceLock.lockForWrite();
    app_stop_charge_service_.replace(gunno, false);
    AppStopChargeServiceLock.unlock();
}

bool OiovReqMain::CardAuthStartChargeService(quint8 gunno)
{
    bool res = false;

    CardAuthStartChargeServiceLock.lockForRead();
    res = card_auth_start_charge_service_.at(gunno);
    CardAuthStartChargeServiceLock.unlock();

    return res;
}

void OiovReqMain::SetCardAuthStartChargeService(quint8 gunno)
{
    CardAuthStartChargeServiceLock.lockForWrite();
    card_auth_start_charge_service_.replace(gunno, true);
    CardAuthStartChargeServiceLock.unlock();
}

void OiovReqMain::ClearCardAuthStartChargeService(quint8 gunno)
{
    CardAuthStartChargeServiceLock.lockForWrite();
    card_auth_start_charge_service_.replace(gunno, false);
    CardAuthStartChargeServiceLock.unlock();
}

void OiovReqMain::SetCardAuthChargeEvent(quint8 gunno)
{
    CardAuthChargeEventLock.lockForWrite();
    card_auth_charge_event_.replace(gunno, true);
    CardAuthChargeEventLock.unlock();
}

void OiovReqMain::SetStopChargeEvent(quint8 gunno)
{
    StopChargeEventLock.lockForWrite();
    stop_charge_event_.replace(gunno, true);
    StopChargeEventLock.unlock();
}

void OiovReqMain::SetRebillChargeEvent()
{
    rebill_charge_event_ = true;
}

void OiovReqMain::SetDeviceStatusEvent(quint8 gunno)
{
    DeviceStatusEventLock.lockForWrite();
    device_status_event_.replace(gunno, true);
    DeviceStatusEventLock.unlock();
}

void OiovReqMain::SetHearbeatEvent(quint8 gunno)
{
    HearbeatEventLock.lockForWrite();
    hearbeat_event_.replace(gunno, true);
    HearbeatEventLock.unlock();
}

void OiovReqMain::SetChargingProperty(quint8 gunno)
{
    ChargingPropertyLock.lockForWrite();
    charging_property_ .replace(gunno, true);
    ChargingPropertyLock.unlock();
}

void OiovReqMain::ClearChargingProperty(quint8 gunno)
{
    ChargingPropertyLock.lockForWrite();
    charging_property_ .replace(gunno, false);
    ChargingPropertyLock.unlock();
}

void OiovReqMain::run()
{
//#ifndef __arm__
//    return;
//#endif

    quint8 index = 0;
    quint32 heartbeat = 10 * 1000 / m_cycle, chargeing_data[2] = {5 * (60 - 1) * 1000 / 500};

    while (!m_quit) {
        if (!OiovResMain::net_state()) {
            msleep(m_cycle);
            continue;
        }

        /*---------------------------------------------------------------------Update-----------------------------------------------------------------------*/

        //...

        /*--------------------------------------------------------------------heartbeat---------------------------------------------------------------------*/

        if (++heartbeat >= 30 * 1000 / m_cycle) {
            heartbeat = 0x00;
            for (index = 0; index < device_status_event_.size(); index++) {
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "heartbeat...";
#endif
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_HEARTBEAT, &OiovCallback::ops_event_heartbeat[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "heartbeat...";
#endif
            }
        }

        for (int index = 0; index < check_fee_event_.size(); index++) {
            if (Check_Fee(index)) {
                // 如果存在错误，执行清除错误操作
                ClearCheck_Fee(index);

                // 处理错误事件，例如发送错误事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHECK_FEE, &OiovCallback::ops_event_check_fee);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "error event";
#endif

            }
        }

        for (index = 0; index < (uint32_t)(firmware_status_event_.size()); index++) {
            if (FirmwareStatusEvent (index)) {
                ClearFirmwareStatusEvent (index);
                ops_send_event(OPSGUNNOA, OPS_CMD_EVENT_UPDATE_RES, &OiovCallback::ops_active_service_feedback_start_update[index]); // A 抢授权成功后向平台获取计费模型
            }
        }

        if (Req_Fee()) {
            ClearReq_Fee();
            ops_send_event(OPSGUNNOA, OPS_CMD_EVENT_FEE_STRATEGY, &OiovCallback::ops_event_fee_strategy); // A 抢授权成功后向平台获取计费模型
#ifdef OIOVMAIN_DEBUG
            qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << " Req fee event";
#endif
        }




        /*----------------------------------------------------------------------event------------------------------------------------------------------------*/

        for (index = 0; index < device_status_event_.size(); index++) {
            if (DeviceStatusEvent(index)) {
                ClearDeviceStatusEvent(index);
                ops_send_property(index + OPSGUNNOA, OPS_CMD_PROPERTY_CHARG_DATA, &OiovCallback::ops_property_charge_data[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge data... (event)";
#endif
            }
        }

        for (index = 0; index < stop_charge_event_.size(); index++) {
            if (StopChargeEvent(index)) {
                ClearStopChargeEvent(index);
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_BILL, &OiovCallback::ops_event_bill[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "bill data...";
#endif
            }
        }

        if (RebillChargeEvent()) {
            ClearRebillChargeEvent();
            if (0x01 == OiovCallback::ops_event_rebill.gun_number) {
                ops_send_event(OPSGUNNOA, OPS_CMD_EVENT_BILL, &OiovCallback::ops_event_rebill);
            } else if (0x02 == OiovCallback::ops_event_rebill.gun_number) {
                ops_send_event(OPSGUNNOB, OPS_CMD_EVENT_BILL, &OiovCallback::ops_event_rebill);
            } else {
                //...
            }
#ifdef OIOVMAIN_DEBUG
            qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "bill data... ( GunNumber: " << OiovCallback::ops_event_rebill.gun_number << ")";
#endif
        }

        for (index = 0; index < card_auth_charge_event_.size(); index++) {
            if (CardAuthChargeEvent(index)) {
                ClearCardAuthChargeEvent(index);
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CARD_AUTH, &OiovCallback::ops_event_card_authorize[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "card auth data...";
#endif
            }
        }


        for (index = 0; index < Charge_Handshake_.size(); index++) {
            if (Charge_Handshake(index)) {
                ClearCharge_Handshake(index);
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_HANDSHAKE, &OiovCallback::ops_event_charge_handshake[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "bill data...";
#endif
            }
        }

        for (int index = 0; index < BMS_Charge_Complete_.size(); index++) {
            if (BMS_Charge_Complete(index)) {
                // 如果充电完成，执行清除操作
                ClearBMS_Charge_Complete(index);

                // 处理相关事件，例如发送事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHARGE_COMPLETE, &OiovCallback::ops_event_charge_complete[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge complete event";
#endif

            }
        }

        for (int index = 0; index < BMS_Error_.size(); index++) {
            if (BMS_Error(index)) {
                // 如果存在错误，执行清除错误操作
                ClearBMS_Error(index);

                // 处理错误事件，例如发送错误事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_ERROR, &OiovCallback::ops_event_error[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "error event";
#endif
            }
        }

        for (int index = 0; index < BMS_Set_Value_.size(); index++) {
            if (BMS_Set_Value(index)) {
                // 如果存在错误，执行清除错误操作
                ClearBMS_Set_Value(index);

                // 处理错误事件，例如发送错误事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_SET_VALUE, &OiovCallback::ops_event_set_value[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "error event";
#endif

            }
        }


        for (int index = 0; index < BMS_Charge_Abort_.size(); index++) {
            if (BMS_Charge_Abort(index)) {
                // 如果充电中止，执行清除操作
                ClearBMS_Charge_Abort(index);

                // 处理充电中止事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHARGE_ABORT, &OiovCallback::ops_event_charge_abort[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge abort event";
#endif

            }
        }

        for (int index = 0; index < BMS_Charge_Stop_.size(); index++) {
            if (BMS_Charge_Stop(index)) {
                // 如果充电停止，执行清除操作
                ClearBMS_Charge_Stop(index);

                // 处理充电停止事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHARGE_STOP, &OiovCallback::ops_event_charge_stop[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge stop event";
#endif

            }
        }

        for (int index = 0; index < BMS_Charge_Output_.size(); index++) {
            if (BMS_Charge_Output(index)) {  // 如果输出状态为 true
                // 执行充电输出相关操作
                ClearBMS_Charge_Output(index);

                // 处理充电输出事件
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHARGE_OUTPUT, &OiovCallback::ops_event_charge_output[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge output event";
#endif

            }
        }



        for (int index = 0; index < BMS_Process_Status_.size(); index++) {

            if (BMS_Process_Status(index)) {  // 假设0表示充电过程正常
                // 充电过程中发生变化，执行状态设置操作
                ClearBMS_Process_Status(index);

                // 处理充电过程状态变化
                ops_send_event(index + OPSGUNNOA, OPS_CMD_EVENT_CHARGE_PROCESS_STATUS, &OiovCallback::ops_event_charge_process_status[index]);
#ifdef OIOVMAIN_DEBUG
                qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge process status event";
#endif

            }
        }
        /*---------------------------------------------------------------------property----------------------------------------------------------------------*/

        for (index = 0; index < charging_property_ .size(); index++) {
            if (ChargingProperty(index)) {
                if (++chargeing_data[index] > 15 * 1000 / 500) {
                    chargeing_data[index] = 0;
                    ops_send_property(index + OPSGUNNOA, OPS_CMD_PROPERTY_CHARG_DATA, &OiovCallback::ops_property_charge_data[index]);
#ifdef OIOVMAIN_DEBUG
                    qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge data... (property)";
#endif
                }
            } else {
                if (++chargeing_data[index] > 5 * 60 * 1000 / 500) {
                    chargeing_data[index] = 0;
                    ops_send_property(index + OPSGUNNOA, OPS_CMD_PROPERTY_CHARG_DATA, &OiovCallback::ops_property_charge_data[index]);
#ifdef OIOVMAIN_DEBUG
                    qDebug() << "[OIOV]->" << (index ? "No.b" : "No.a") << "charge data... (property)";
#endif
                }
            }
        }

        msleep(m_cycle);
    }
}

void OiovReqMain::SetStartUpdate(bool startUpdate)
{
    start_update_ = startUpdate;
}

bool OiovReqMain::CardAuthChargeEvent(quint8 gunno)
{
    bool res = false;

    CardAuthChargeEventLock.lockForRead();
    res = card_auth_charge_event_.at(gunno);
    CardAuthChargeEventLock.unlock();

    return res;
}

bool OiovReqMain::StopChargeEvent(quint8 gunno)
{
    bool res = false;

    StopChargeEventLock.lockForRead();
    res = stop_charge_event_.at(gunno);
    StopChargeEventLock.unlock();

    return res;
}

bool OiovReqMain::RebillChargeEvent()
{
    return rebill_charge_event_;
}

bool OiovReqMain::DeviceStatusEvent(quint8 gunno)
{
    bool res = false;

    DeviceStatusEventLock.lockForRead();
    res = device_status_event_.at(gunno);
    DeviceStatusEventLock.unlock();

    return res;
}

bool OiovReqMain::HearbeatEvent(quint8 gunno)
{
    bool res = false;

    HearbeatEventLock.lockForRead();
    res = hearbeat_event_.at(gunno);
    HearbeatEventLock.unlock();

    return res;
}

void OiovReqMain::ClearCardAuthChargeEvent(quint8 gunno)
{
    CardAuthChargeEventLock.lockForWrite();
    card_auth_charge_event_.replace(gunno, false);
    CardAuthChargeEventLock.unlock();
}

void OiovReqMain::ClearStopChargeEvent(quint8 gunno)
{
    StopChargeEventLock.lockForWrite();
    stop_charge_event_.replace(gunno, false);
    StopChargeEventLock.unlock();
}

void OiovReqMain::ClearRebillChargeEvent()
{
    rebill_charge_event_ = false;
}

void OiovReqMain::ClearDeviceStatusEvent(quint8 gunno)
{
    DeviceStatusEventLock.lockForWrite();
    device_status_event_.replace(gunno, false);
    DeviceStatusEventLock.unlock();
}

void OiovReqMain::ClearHearbeatEvent(quint8 gunno)
{
    HearbeatEventLock.lockForWrite();
    hearbeat_event_.replace(gunno, false);
    HearbeatEventLock.unlock();
}

bool OiovReqMain::ChargingProperty(quint8 gunno)
{
    bool res = false;

    ChargingPropertyLock.lockForRead();
    res = charging_property_ .at(gunno);
    ChargingPropertyLock.unlock();

    return res;
}
